import os
import time
import json
import random
import logging
import requests
import exifread

logging.basicConfig(level=logging.CRITICAL)
KEY = "169d2dd7829fe45690fabec812d05bc3"


# 获取gps实体地址
def address(gps):
    global KEY
    try:
        # 随机UA
        _ulist = [
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1",
            "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0",
            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; InfoPath.2; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; 360SE)",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
            "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; Tablet PC 2.0; .NET4.0E)",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)",
            "Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10",
            "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; ja) Presto/2.10.289 Version/12.00",
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36"
        ]
        # 伪造header
        _header = {
            "User-Agent": random.choice(_ulist),
            "Accept": "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01",
            "Accept-Encoding": "gzip, deflate, sdch",
            "Accept-Language": "zh-CN,zh;q=0.8",
            "Referer": "http://www.gpsspg.com",
        }
        _res = requests.get(
            "http://restapi.amap.com/v3/geocode/regeo?key={2}&s=rsv3&location={1},{0}&platform=JS&logversion=2.0&sdkversion=1.3&appname=http%3A%2F%2Fwww.gpsspg.com%2Fiframe%2Fmaps%2Famap_161128.htm%3Fmapi%3D3&csid=945C5A2C-E67F-4362-B881-9608D9BC9913".format(gps[0], gps[1], KEY), headers=_header, timeout=(5, 5))
        _json = _res.json()
        # 判断是否取得数据
        if _json and _json["status"] == "1" and _json["info"] == "OK":
            # 返回对应地址
            return _json.get("regeocode").get("formatted_address")
    except Exception as e:
        pass


# 获取指导目录全部的图片路径
def jpgwalk(path, types):
    _start = time.time()
    _pools = []
    # 遍历该目录 并判断files后缀 如符合规则则拼接路径
    for _root, _dirs, _files in os.walk(path):
        _pools.extend([_root.replace("\\", "/") + "/" +
                       _item for _item in _files if _item.split(".")[-1].lower() in types and "$" not in _root])
    print("| Find %s \n| Time %.3fs" % (len(_pools), time.time() - _start))
    return _pools

# 获取EXIF信息


def getEXIF(filepath):
    _showlist = [
        'GPS GPSDOP',
        'GPS GPSMeasureMode',
        'GPS GPSAltitudeRef',
        'GPS GPSAltitude',
        'Image Software',
        'Image Model',
        'Image Make'
    ]
    _XYlist = ["GPS GPSLatitude", "GPS GPSLongitude"]
    _TimeList = ["EXIF DateTimeOrigina", "Image DateTime", "GPS GPSDate"]
    _infos = {
        'Filename': filepath
    }
    with open(filepath, "rb") as _files:
        _tags = None
        # 尝试去的EXIF信息
        try:
            _tags = exifread.process_file(_files)
        except KeyError:
            return
        # 判断是否存在地理位置信息
        _tagkeys = _tags.keys()
        if _tags and len(set(_tagkeys) & set(_XYlist)) == 2 and cg(str(_tags["GPS GPSLongitude"])) != 0.0:
            for _item in sorted(_tagkeys):
                if _item in _showlist:
                    _infos[_item.split()[-1]] = str(_tags[_item]).strip()
            # 经纬度取值
            _infos["GPS"] = (cg(str(_tags["GPS GPSLatitude"])) * float(1.0 if str(_tags.get("GPS GPSLatitudeRef", "N")) == "N" else -1.0),
                             cg(str(_tags["GPS GPSLongitude"])) * float(1.0 if str(_tags.get("GPS GPSLongitudeRef", "E")) == "E" else -1.0))
            # 获取实体地址
            _infos["address"] = address(_infos["GPS"])
            # 获取照片海拔高度
            if "GPS GPSAltitudeRef" in _tagkeys:
                try:
                    _infos["GPSAltitude"] = eval(_infos["GPSAltitude"])
                except ZeroDivisionError:
                    _infos["GPSAltitude"] = 0
                _infos["GPSAltitude"] = "距%s%.2f米" % ("地面" if int(
                    _infos["GPSAltitudeRef"]) == 1 else "海平面", _infos["GPSAltitude"])
                del _infos["GPSAltitudeRef"]

            # time
            _timeitem = list(set(_TimeList) & set(_tagkeys))
            if _timeitem:
                _infos["Dates"] = str(_tags[_timeitem[0]])
            return _infos


# 经纬度格式化
def cg(i):
    try:
        _ii = [float(eval(x)) for x in i[1:][:-1].split(', ')]
        _res = _ii[0] + _ii[1] / 60 + _ii[2] / 3600
        return _res
    except ZeroDivisionError:
        return 0


# 主函数
def main():
    # 预设后缀列表
    types = ["bmp", "jpg", "tiff", "gif", "png"]
    picex = []
    # 文件存储路径
    saves = "$" + input("| SavePath: ").strip()
    # 文件搜索路径 并遍历所有文件返回文件路径列表
    pools = jpgwalk(input("| FindPath: "), types)
    savep = "%s/%s" % (os.getcwd().replace("\\", "/"), saves)
    if savep in pools:
        pools.remove(savep)
    # 遍历列表并获取exif信息
    for path in pools:
        res = getEXIF(path)
        if res:
            picex.append(res)
    # 结果报告
    print("| Result %s" % len(picex))
    # 如果存在结果 保存结果到json并讲相关图片复制到该目录下
    if picex:
        if not os.path.exists(saves):
            os.mkdir(saves)
        with open("%s/%s.json" % (saves, saves), "wb") as f:
            f.write(json.dumps(picex, ensure_ascii=False, indent=4).encode("utf8"))
        for item in picex:
            source_path = item["Filename"]
            with open("%s/%s" % (saves, source_path.split("/")[-1]), "wb") as f_in:
                with open(source_path, "rb") as f_out:
                    f_in.write(f_out.read())

if __name__ == '__main__':
    main()
